package com.whfp.coky.ui.base

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.viewbinding.ViewBinding
import com.whfp.coky.api.HttpUtil
import com.whfp.coky.api.RequestBodyBuild
import com.whfp.coky.api.error.ErrorResult
import com.whfp.coky.api.error.ErrorUtil
import com.whfp.coky.api.response.BaseResult
import com.whfp.coky.api.response.ListBean
import com.whfp.coky.ui.task.model.CheckDeviceBean
import com.whfp.coky.utils.InfoTool
import com.whfp.coky.utils.LogUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch


open class BaseViewModel<VB : ViewBinding> : ViewModel() {

    val httpUtil by lazy { HttpUtil.getInstance().getService() }
    var isShowLoading = MutableLiveData<Boolean>()//是否显示loading
    var errorData = MutableLiveData<ErrorResult>()//错误信息
    lateinit var vBinding: VB

    var checkedDevLD = MutableLiveData<CheckDeviceBean>()//校验后的设备信息

    fun binding(vb: VB) {
        this.vBinding = vb
    }

    open fun observe(activity: BaseActivity<*,*>, owner: LifecycleOwner) {

    }

    open fun observe(fragment: BaseFragment<*,*>, owner: LifecycleOwner) {

    }

    private fun showLoading() {
        isShowLoading.value = true
    }

    private fun dismissLoading() {
        isShowLoading.value = false
    }

    private fun showError(error: ErrorResult) {
        kotlin.runCatching { suspend { delay(1000) } }.onSuccess {  }
        errorData.value = error
    }

    /**
     * 请求接口，可定制是否显示loading和错误提示
     * block：闭包（功能代码块，定义了其，为返回值为BaseResult的协程），
     * 相当于 val block={ suspend { httpUtil.getArticleList(page) } }
     *       val result=block()
     */
    fun <T> launch(
        block: suspend CoroutineScope.() -> BaseResult<T>,//请求接口方法，T表示data实体泛型，调用时可将data对应的bean传入即可
        liveData: MutableLiveData<T>,
        isShowLoading: Boolean = false,
        isShowError: Boolean = true
    ) {
        if (isShowLoading) showLoading()
        viewModelScope.launch {
            try {
                val result = block()
                if (isHttpSuccess(result)) {//请求成功
                    liveData.value = result.data
                } else {
                    LogUtil.e("请求错误>>" + result.msg)
                    showError(ErrorResult(result.result, result.msg, isShowError))
                }
            } catch (e: Throwable) {//接口请求失败
                LogUtil.e("请求异常>>" + e.message)
                val errorResult = ErrorUtil.getError(e)
                errorResult.show = isShowError
                showError(errorResult)
            } finally {//请求结束
                dismissLoading()
            }
        }
    }

    /**
     *
     * 获取recyclerview的数据
     */
    fun <T> launchList(
        block: suspend CoroutineScope.() -> BaseResult<ListBean<T>>,//请求接口方法，T表示data实体泛型，调用时可将data对应的bean传入即可
        liveData: MutableLiveData<ListBean<T>>,
        isShowLoading: Boolean = false,
        isShowError: Boolean = true
    ) {
        if (isShowLoading) showLoading()
        viewModelScope.launch {
            try {
                val result = block()
                if (isHttpSuccess(result)) {//请求成功
                    LogUtil.e("isHttpSuccess......")
                    liveData.value = result.data
                } else {
                    LogUtil.e("请求错误>>" + result.msg)
                    showError(ErrorResult(result.result, result.msg, isShowError))
                }
            } catch (e: Throwable) {//接口请求失败
                LogUtil.e("请求异常>>" + e.message)
                val errorResult = ErrorUtil.getError(e)
                errorResult.show = isShowError
                showError(errorResult)
            } finally {//请求结束
                dismissLoading()
            }
        }
    }


    //        校验设备二维码信息
    fun doVerDevice(codeResult: String) {
        val map = HashMap<String, String>()
        map["deviceMac"] = InfoTool.buildPhoneMac()
        map["deviceInfo"] = codeResult
        launch(
            { httpUtil.doDevCheck(body = RequestBodyBuild.buildBodyByMap(map)) },
            checkedDevLD,
            true
        )
    }


   open fun isHttpSuccess(result:BaseResult<*>):Boolean = result.isSuccess()


}
